package comnet.rmi;

import java.rmi.RemoteException;
import java.rmi.server.RemoteObject;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collection;

/**
 * @author Mikko Puustinen (mikko.puustinen@gmail.com)
 * @version 0.1, 2008-jan-15
 */
@SuppressWarnings({"SynchronizedMethod"})
public class RmiServer extends UnicastRemoteObject implements ChatActions {
    private static final long serialVersionUID = 6186872225356138416L;
    private static Collection<ClientActions> connectedUsers;

    public RmiServer() throws RemoteException {
        super();
        connectedUsers = new ArrayList<ClientActions>();
    }

    private static String printAllConnected(ClientActions ca) throws RemoteException {
        StringBuilder sb = new StringBuilder();
        synchronized(connectedUsers) {
            for (ClientActions c : connectedUsers) {
                try {
                    sb.append(c.getNickName());
                    if (!RemoteObject.toStub(ca).equals(c)) {
                        sb.append(" (You)");
                    }
                    sb.append("\n");
                } catch (RemoteException e) {
                    quitSession(c);
                }
            }
        }

        return sb.toString();
    }

    private static void broadCastMessage(ClientActions sender, String message) throws RemoteException {
        synchronized(connectedUsers) {
            for (ClientActions c : connectedUsers) {
                try {
                    if (sender == null) {
                        c.notifyNewMessage(message);
                    } else {
                        if (!RemoteObject.toStub(sender).equals(c)) {
                            c.notifyNewMessage(message);
                        }
                    }
                } catch (RemoteException e) {
                    quitSession(c);
                }
            }
        }
    }

    public void newMessage(ClientActions ca, String message) throws RemoteException {
        if (message.startsWith("/quit")) {
            quitSession(ca);
        } else if (message.startsWith("/who")) {
            sendMessage(ca, printAllConnected(ca));
        } else if (message.startsWith("/nick")) {
            String[] n = message.split(" ");
            String temp = ca.getNickName();
            if (n.length > 1) {
                ca.setNickName(n[1]);
                broadCastMessage(null, "** " + temp + " changed name to " + n[1]);
            }
        } else {
            broadCastMessage(ca, message);
        }
    }

    public void registerSession(ClientActions ca) throws RemoteException {
        synchronized(connectedUsers) {
            connectedUsers.add(ca);
        }
        broadCastMessage(null, "User connected");
    }

    private static void sendMessage(ClientActions ca, String message) throws RemoteException {
        ca.notifyNewMessage(message);
    }

    private static void quitSession(ClientActions ca) throws RemoteException {
        synchronized(connectedUsers) {
            connectedUsers.remove(ca);
        }
        broadCastMessage(null, "User disconnected");
        ca.endSession();
    }
}